using System;
using System.Drawing;
using System.Windows.Forms;
using needle.UI.Controls.Flat.Windows.Forms.Helpers;

namespace needle.UI.Controls.Flat.Windows.Docking
{
    public class HotZoneFloating : HotZone
    {
        protected Point moffset;
        protected Point mdrawPos;
        protected Rectangle mdrawRect;
        protected RedockerContent mredocker;

		#region Constructors

		public HotZoneFloating(Rectangle hotArea, Rectangle newSize, Point offset, RedockerContent redocker) : base(hotArea, newSize)
        {
            moffset = offset;
            mredocker = redocker;

            Size floatSize = CalculateFloatingSize();
            float widthPercentage = (float)floatSize.Width / (float)mnewSize.Width;
            float heightPercentage = (float)floatSize.Height / (float)mnewSize.Height;

            mnewSize.Width = floatSize.Width;
            mnewSize.Height = floatSize.Height + SystemInformation.ToolWindowCaptionHeight;
            
            moffset.X = (int)((float) moffset.X * widthPercentage);
            moffset.Y = (int)((float) moffset.Y * heightPercentage);

			if (moffset.X > newSize.Width)
				moffset.X = newSize.Width;

			if (moffset.Y > newSize.Height)
				moffset.Y = newSize.Height;
        }

		#endregion

		#region Overrides

        public override bool ApplyChange(Point screenPos, Redocker parent)
        {
            RedockerContent redock = parent as RedockerContent;
            DockingManager dockingManager = redock.DockingManager;

            Zone newZone = null;
            
            dockingManager.RemoveShowingAutoHideWindows();

            switch(redock.DockingSource)
            {
                case RedockerContent.Source.RawContent:
                    {
                        redock.Content.ContentBecomesFloating();

                        Window w = dockingManager.CreateWindowForContent(redock.Content);

                        newZone = dockingManager.CreateZoneForContent(State.Floating);
                        
                        newZone.Windows.Add(w);
                    }
                    break;
                case RedockerContent.Source.WindowContent:
                    foreach(Content c in redock.WindowContent.Contents)
                        c.ContentBecomesFloating();

                    if (redock.WindowContent.ParentZone != null)
                        redock.WindowContent.ParentZone.Windows.Remove(redock.WindowContent);

                    newZone = dockingManager.CreateZoneForContent(State.Floating);
                    
                    newZone.Windows.Add(redock.WindowContent);
                    break;
                case RedockerContent.Source.ContentInsideWindow:
                    {
                        redock.Content.ContentBecomesFloating();

                        if (redock.Content.ParentWindowContent != null)
                            redock.Content.ParentWindowContent.Contents.Remove(redock.Content);
    				
                        Window w = dockingManager.CreateWindowForContent(redock.Content);

                        newZone = dockingManager.CreateZoneForContent(State.Floating);
                        
                        newZone.Windows.Add(w);
                    }
                    break;
                case RedockerContent.Source.FloatingForm:
                    redock.FloatingForm.Location = new Point(screenPos.X - moffset.X,
                                                             screenPos.Y - moffset.Y);

                    return false;
            }
        
			dockingManager.UpdateInsideFill();

            FloatingForm floating = new FloatingForm(redock.DockingManager, newZone,
                                                     new ContextEventHandler(dockingManager.OnShowContextMenu));

            mdrawRect = new Rectangle(screenPos.X, screenPos.Y, mnewSize.Width, mnewSize.Height);

            mdrawRect.X -= moffset.X;
            mdrawRect.Y -= moffset.Y;

            floating.Location = new Point(mdrawRect.Left, mdrawRect.Top);
            floating.Size = new Size(mdrawRect.Width, mdrawRect.Height);

            floating.Show();

            return true;
        }

        public override void UpdateForMousePosition(Point screenPos, Redocker parent)
        {
            Point newPos = screenPos;

            Rectangle newRect = new Rectangle(newPos.X, newPos.Y, mnewSize.Width, mnewSize.Height);

            newRect.X -= moffset.X;
            newRect.Y -= moffset.Y;

            GraphicsUtils.DrawDragRectangles(new Rectangle[]{mdrawRect,newRect}, mdragWidth);

			mdrawPos = newPos;
			mdrawRect = newRect;
        }

        public override void DrawIndicator(Point mousePos) 
        {
            mdrawPos = mousePos;

            mdrawRect = new Rectangle(mdrawPos.X, mdrawPos.Y, mnewSize.Width, mnewSize.Height);

            mdrawRect.X -= moffset.X;
            mdrawRect.Y -= moffset.Y;

            DrawReversible(mdrawRect);
        }
		
        public override void RemoveIndicator(Point mousePos) 
        {			
            DrawReversible(mdrawRect);
        }

		#endregion

		#region Virtuals

		protected Size CalculateFloatingSize()
		{
			Size floatingSize = new Size(0,0);

			RedockerContent redock = mredocker as RedockerContent;

			switch(redock.DockingSource)
			{
				case RedockerContent.Source.RawContent:
					floatingSize = redock.Content.FloatingSize;
					break;
				case RedockerContent.Source.WindowContent:
					foreach(Content c in redock.WindowContent.Contents)
					{
						if (c.FloatingSize.Width > floatingSize.Width)
							floatingSize.Width = c.FloatingSize.Width;
                    
						if (c.FloatingSize.Height > floatingSize.Height)
							floatingSize.Height = c.FloatingSize.Height;
					}

					foreach(Content c in redock.WindowContent.Contents)
						c.FloatingSize = floatingSize;
					break;
				case RedockerContent.Source.ContentInsideWindow:
					floatingSize = redock.Content.FloatingSize;
					break;
				case RedockerContent.Source.FloatingForm:
					floatingSize.Width = mnewSize.Width;
					floatingSize.Height = mnewSize.Height;
					break;
			}

			return floatingSize;
		}

		#endregion
    }
}
